(function($) { 

    function init(sod, widget, dom) {
 
    	var model = sod.model;
    	if(!widget.state){
    		widget.state = [];
    	}
	
	var states = widget.state;
	for( var i =0 ; i < states.length ; i++ ){
		if( "null-a" == states[i].s ){
			states[i].s = "1-a";		
		} 
	}	


    	var rpc = sod.sod("getRPC");
    	var apply = function(mod ,e) {
            if(e) { alert(e.message); return; }

    		mod = eval('(' + mod + ')');
    		dom.html("<div style='width: 100%; overflow-x: auto;'>"+mod.html+"</div>");
    		createBehavior(sod, widget , dom , mod, rpc , apply);
    		sod.sod("updateState");
    	};
    	rpc.sod.createRelationObjectsMOD(apply, model.q, JSON.stringify(widget), model.cid);
    }
    
     var defaultBehavior = {
    	    image: function(sod, column) {
    	    	sod.find("td.SodTop [smcol="+column+"] a").slimbox({
    	            loop: true,
    	            overlayOpacity: 0.4,
    	            imageFadeDuration: 1,
    	            resizeDuration: 50,
//    	                    resizeDuration: 1000,
//    	                    resizeEasing: "easeOutElastic",
    	            captionAnimationDuration: 1
    	        });
    	    },
    	    
    	    matrix: function(mod, column) {
    	        var matrixDivs = mod.find("td.SodTop div.matrix ");
    	        matrixDivs.click(function(){
    	        	var jDiv = $(this);
    	        	var dialog = jDiv.clone();
    	        	dialog.unbind('click');
    	        	var jTable= dialog.find("table.dlgTab");
    	        	jTable.show();
    				var d = dialog.dialog({ title: 'matrix',
    				    width: 'auto', height: 'auto', modal: true
    				});
    				
    				        	
    	        });
    	        loadMatrix(matrixDivs, 0);
    	    },
    	  
    	    scaleImage : function(sod,column) {
    	        var t = i18n('mod.scaleImage');
    	        sod.find("td.SodTop [smcol="+column+"]").click( function() {
    	            openDialog("scaleImage", { "title" : t }, mod, column);
    	        });
    	        defaultBehavior['image'](sod, column);
    	    }
    	};
     
     function columnBehavior(sod,name, column) {
         var func = defaultBehavior[name];
         if(!func) return;
         func(sod, column);
     	}
    
    function createBehavior(sod, widget, dom, mod, rpc, apply){
    	var model = sod.model;
    	var data = {"sod" : sod , "widget" : widget};
    	// this.find("table.ModBody th[menu*=col_]").hover(highColumnHeader, unhighColumnHeader);
        var img = getContextPath()+"/mod/jquery/mbMenu/ico/";
        dom.find("table.ModBody").buildMenu({
            menuWidth:200,
            rpc: buildColumnMenu,
            data : data,
            openOnRight:false,
            menuSelector: ".menuContainer",
            iconPath: img,
            hasImages:true,
            fadeInTime:100,
            fadeOutTime:100,
            adjustLeft:2,
            adjustTop:10,
            hoverIntent:0,
            openOnClick:true,
            closeAfter:1000,
            submenuHoverIntent:200
        });
      
        
        dom.find("table.MOD").buildMenu({
            menuWidth:200,
            rpc: buildGlobalMenu,
            openOnRight:false,
            data : data,
            menuSelector: ".menuContainer",
            iconPath: img,
            hasImages:false,
            fadeInTime:100,
            fadeOutTime:100,
            adjustLeft:2,
            adjustTop:10,
            hoverIntent:0,
            openOnClick:true,
            closeAfter:1000,
            submenuHoverIntent:200
        });

        var url = getContextPath()+"/mod/global/selectRows.js";
     	var js = sod.sod("getFileByUrl",url);
     	var handlers = eval(js);
        dom.find("[oid]").hover(highlightRow, unhighlightRow)
        				 .dblclick(initExternalListeners)
        				 .click(function(event){
        					 handlers.onShow.call(this,event,this,sod ,widget);
        				 });
        dom.find("[oid]").buildContextualMenu({
            rpc: buildContextMenu,
            menuWidth:200,
            openOnRight:true,
            data : data,
            menuSelector: ".menuContainer",
            iconPath: img,
            hasImages:true,
            fadeInTime:100,
            fadeOutTime:100,
            adjustLeft:2,
            adjustTop:10,
            hoverIntent:0,
            openOnClick:true,
            closeAfter:1000,
            submenuHoverIntent:200
        });
        

        var relation = fetchAndUpdateRelationState(widget, mod, sod, dom);

		// relation change
        var sRel = dom.find("select#rel");
        if(sRel.children('option').length < 2) {
            var l = $("<span></span>");
            l.text(sRel.children('option').eq(0).text());
            l.css('display', 'none');
            sRel.replaceWith(l);
        } else {
            sRel.change(function(){
            	debugger
            	//alert("-----");
                widget.defRL = this.selectedIndex;
                rpc.sod.createRelationObjectsMOD(apply, model.q , JSON.stringify(widget), model.cid );
            });
        }
        
        dom.find('#modPagerHFill').html("<a id='detach' href='javascript:processMod(\""+model.cid+"\", \"manyRef\", \""+mod.q+"\")'><img class='ModButton' src='../../sod/img/detach.png' alt='' title='Detach: open table in its own work space.' style='float: right;'></img></a>");
        var th = dom.find("th[behavior]");
        $.each(th,function(i,col){
        	col = $(col);
        	var behavior = col.attr('behavior');
        	columnBehavior(sod,behavior,i);
        })
		//Page size change
		var pager = dom.find("table.ModPager td.MODComp");
		var viewAnchors = pager.find('a img.ModGridButton');
		viewAnchors.each(function() {
			$(this).parent().removeAttr("href");
		}).click(
				function() {
					var jImg = $(this);
					jImg.parent().removeAttr("href");
					var view = jImg.attr("title");
					(view == 'Grid View') ? relation.l = 'GRID'
							: relation.l = 'TABLE';
					rpc.sod.createRelationObjectsMOD(apply, model.q, JSON
							.stringify(widget), model.cid);

				});
		
		pager.find("input:button").removeAttr("onclick").click(function(){
			var val = pager.find("input.gototext").val();
			val = parseInt(val);
			if(val < 1){
				 pager.find("input.gototext").val(relation.pn + 1);
				return;
			}
			else
				relation.pn = val -1;
	    	rpc.sod.createRelationObjectsMOD(apply,model.q , JSON.stringify(widget), model.cid );
		});
		
		// Page first click
		pager.find("a.pagefirst ").removeAttr("href").click(function(){
			if($(this).hasClass("pager-disable")) return;
			relation.pn =0;
	    	rpc.sod.createRelationObjectsMOD(apply,model.q , JSON.stringify(widget),model.cid );
		});
		// Page previous link click
		pager.find("a.pagePrevLink").removeAttr("href").click(function(){
			if($(this).hasClass("pager-disable")) return;
			relation.pn =rpc.sod.getPreviousLinkPageNumber(model.q , JSON.stringify(widget),model.cid);
	    	rpc.sod.createRelationObjectsMOD(apply,model.q , JSON.stringify(widget),model.cid );
		});
		
		// Page prev click
		pager.find("a.pageprev").removeAttr("href").click(function(){
			if($(this).hasClass("pager-disable")) return;
			relation.pn =relation.pn-1;
	    	rpc.sod.createRelationObjectsMOD(apply,model.q , JSON.stringify(widget),model.cid );
		});
		// Page number click
		pager.find("a.num").removeAttr("href").click(function(){
			var p = $(this).text();
			p = parseInt(p);
			relation.pn =p-1;
	    	rpc.sod.createRelationObjectsMOD(apply,model.q , JSON.stringify(widget),model.cid );
		});
		
		// Page next click
		pager.find("a.pagenext").removeAttr("href").click(function(){
			if($(this).hasClass("pager-disable")) return;
			relation.pn =relation.pn+1;
	    	rpc.sod.createRelationObjectsMOD(apply,model.q , JSON.stringify(widget),model.cid );
		});
		
		// Page next link click
		pager.find("a.pagenextlink").removeAttr("href").click(function(){
			if($(this).hasClass("pager-disable")) return;
			relation.pn = rpc.sod.getNextLinkPageNumber(model.q , JSON.stringify(widget),model.cid);
	    	rpc.sod.createRelationObjectsMOD(apply,model.q , JSON.stringify(widget),model.cid );
		});
		
		// Page last click
		pager.find("a.pagelast").removeAttr("href").click(function(){
			if($(this).hasClass("pager-disable")) return;
			var totalPageCount = relation.t/relation.ps;
			var remiander = relation.t % relation.ps;
			if(remiander > 0)
				totalPageCount = totalPageCount + 1;
			relation.pn =totalPageCount-1;
	    	rpc.sod.createRelationObjectsMOD(apply,model.q , JSON.stringify(widget),model.cid );
		});
	 	var pagerDD = pager.find("select");
		pagerDD.removeAttr("onchange");
		pagerDD.change(function(){
			relation.ps = $(this).val();
	    	rpc.sod.createRelationObjectsMOD(apply,model.q , JSON.stringify(widget),model.cid );
		});
		
    }
    
    function buildContextMenu(node,event,data){
    	var url = getContextPath()+"/mod/global/modContextMenu.js";
    	var sod = data.sod;
     	var js = sod.sod("getFileByUrl",url);
     	var handlers = eval(js);
        return handlers.onShow.call(this,node,event,sod,data.widget,'launchEmbeddedMODAction');
    }
    
    function highColumnHeader(event) {
        $(this).addClass("ModColumnHigh");
        event.stopPropagation();
    }
        
    function unhighColumnHeader(event) { 
        $(this).removeClass("ModColumnHigh");
        event.stopPropagation();
    }
    
    function highlightRow(event) {
        $(this).addClass("ModHigh");
        event.stopPropagation();
    }
        
    function unhighlightRow(event) { 
        $(this).removeClass("ModHigh");
        event.stopPropagation();
    }
    
    function initExternalListeners(event) {
    	 var id = getComponentId(sod);
    	 var fun = id.replace(/:/g, "_").replace(/-/g, "_");
    	 var result = window["processMod_"+fun];
    	 result.call(result,id,'rowDoubleClick',$(this).attr("oid"));
		 Richfaces.showModalPanel('SMSTATUSDLG-status');
	     deselectText();
	     event.stopPropagation();
    }
    
    function applyCounts(text, e, widget, dom, mod) {
        if(e) { alert(e.message); return; }

        var nums = eval('('+text+')');
        widget.args.hasCounts = nums;
        setCounts(widget, dom, mod);
    }
    
    function setCounts(widget, dom, mod) {
        var nums = widget.args.hasCounts;
        if(nums == 1) return;

        var i = 0;
        dom.find("select#rel option").each(function() {
            var n = nums[i++];
            var o = $(this);
            o.text(o.text()+" ("+n+")");
            if(!n) o.attr('disabled','disabled');
        });
        
        if(!nums[mod.defRL]) { // no objects on current relation
            var a = dom.find('#detach');
            a.removeAttr("href");
            a.find('img').addClass('ModButtonDisabled').removeAttr('title');
        }
    }
    
    function fetchAndUpdateRelationState(widget, mod, sod, dom) {
        if(mod.newRL) { // new relations after split-by-type
            widget.args.splitByType = "false";
            widget.state = [];
            widget.fields = mod.newRL;
        }
        
        if(!widget.args.hasCounts) {
            widget.args.hasCounts = 1;
            var model = sod.model;
            var rpc = newRpcClient();
            rpc.sod.countRelations(
                function(t, e) { applyCounts(t, e, widget, dom, mod); },
                model.q, JSON.stringify(widget));
        } else {
            setCounts(widget, dom, mod);
        }
        
    	var rl = mod.defRL;
    	var rlJson = null;
    	for(var i = 0; i < widget.state.length ; i++){
    		var json = widget.state[i];
    		if(json.rl == rl)
    			rlJson = json;
    	}
    	
debugger 
    	if(rlJson){
    		rlJson.rl = mod.defRL;
    		rlJson.ps = mod.ps;
    		rlJson.pn = mod.pn;
    		rlJson.t  = mod.t;
    		rlJson.s  = mod.s;
    		rlJson.q  = mod.q;
    		rlJson.sl  = mod.sl;
    		rlJson.shsl = mod.shsl;
    	} else {
    		widget.defRL = rl;
        	rlJson = {"rl":mod.defRL,"ps":mod.ps ,"pn":mod.pn ,"t":mod.t , "s":mod.s , "q" :mod.q , "sl":mod.sl, "shsl" :mod.shsl};
        	widget.state.push(rlJson);	
    	}
    	
    	return rlJson;
    }
  
    function buildColumnMenu(node, e, data) {
    	var menu = node.attr('menu');
		var html = "<div id='" + menu+ "' class='mbmenu' >";
		var smNum = node.attr("smcol");
		var sod = data.sod;
		var model = sod.model;
		var widget = data.widget;
		var rpc = sod.sod("getRPC");
		var mod = rpc.sod.createRelationColumnMenu(JSON.stringify(model) ,model.q, JSON.stringify(widget), model.cid,  smNum);
		mod = eval('(' + mod + ')');
		html =html+ mod.html+"</div>";
		return html;
	}
   
    function buildGlobalMenu(node,e,data){
    	var menu = node.attr('menu');
		var html = "<div id='" + menu+ "' class='mbmenu' >";
		var sod = data.sod;
		var model = sod.model;
		var widget = data.widget;
		var rpc = sod.sod("getRPC");
		var mod = rpc.sod.createRelationGlobalMenu(JSON.stringify(model) ,model.q, JSON.stringify(widget), model.cid);
		mod = eval('(' + mod + ')');
		html = html+ mod.html+"</div>";
		return html;
    }
    
    function sort(sod ,model,widget ,data , pointerToDelete){
    	var obj = activeRelationState(widget);
    	var pointer =obj.index;
    	var state = obj.state;
    	var arr =state.s.split(";");
    	var index = hasValue(arr, pointerToDelete);
    	if(index!= -1)
    		arr.splice(index,1);
    	if(data.indexOf("r") == -1){
    		arr.push(data);
    	}
    	state.s = arr.join(";");
    	widget.state[pointer] = state;
    	sod.sod("replaceWidget" , widget);
   	    sod.sod("updateState" );
    	var dom = getDOMByLayout(model, widget);
       	dom.empty(); 
    	init(sod, widget, dom);
    }
    
    function getDOMByLayout(model, widget){
    	var dom = sod.find("[id=content_"+model.curLayout+"]");
    	var c = widget.c;
    	var r = widget.r;
    	dom = dom.find("[col='"+c+"'][row='"+r+"']");
    	return dom;
    }
   
    function filter(sod ,model,widget ,column,type ,url){
    	 var dom = getDOMByLayout(model, widget);
    	 var th = dom.find("th[smcol="+column+"]");
    	 var t = i18n('mod.filter');
         if(type=='unitConversion')
         	t = i18n('mod.unitConversion');
         openDialog(url, { "title" : t }, sod, th ,widget);
       
    }
    
    function filterByType(sod ,model,widget,type,url){
    	 var t = i18n('mod.filterByType');
    	 openDialog(url, { "title" : t }, sod,widget);
    }
    
    function removeFilter(sod ,model,widget ,column , filterIndex){
    	var active = activeRelationState(widget);
    	if(active.state.f) {
    		filterIndex = parseInt(filterIndex);
    		column = parseInt(column);
    		var temp  = 0;
    		for(var i = 0 ; i < active.state.f.length ; i ++ ){
    			var f = active.state.f[i].f;
    			if(f.indexOf(column+";") == -1) continue;
    			if(temp == filterIndex)
    				active.state.f.splice(i , 1);
    			temp++;
    		}
    		
    			
    	}
    	widget.state[active.index] = active.state;
		sod.sod("replaceWidget" , widget);
    	sod.sod("updateState" );
    	var dom = getDOMByLayout(model, widget);
       	dom.empty();
    	init(sod, widget, dom);
    }
   
   function clearFilter(sod,model,widget){
	   var active = activeRelationState(widget);
	   if(active.state.f)
		   active.state.f = "";
	   if(active.state.ft)
		   active.state.ft = "";
	   active.state.sl = ""; 
	   sod.sod("replaceWidget" , widget);
	   sod.sod("updateState" );
	   var dom = getDOMByLayout(model, widget);
   	   dom.empty();
   	   init(sod, widget, dom);
   }
    
   function clearSelection(sod,model,widget){
	   var active = activeRelationState(widget);
	   if(active.state.sl){
		   active.state.sl = ""; 
		   active.state.shsl = false;   
	   }
	   sod.sod("replaceWidget" , widget);
	   sod.sod("updateState" );
	   var dom = getDOMByLayout(model, widget);
   	   dom.empty();
   	   init(sod, widget, dom);
   }
   
   function showCharsPerLine(sod,model,widget,type,url){
	  var t = i18n('mod.charactersPerLine');
  	 openDialog(url, { "title" : t }, sod,widget);
   }
   
   function sodExport(sod,model,widget,type,url){
	   var t = i18n('mod.export');
       openDialog(url, { "title" : t }, sod,widget);
   }
   
   function selectSOD(sod,model,widget,sel){
	   var q = model.q;
	   var cid = model.cid;
	   var rpc = newRpcClient();
       var res = rpc.sod.sodSelect(q,JSON.stringify(widget),cid,sel);
       res = eval('(' + res + ')');
       var active = activeRelationState(widget);
       active.state.sl = res.sl;
       if(res.msg!=""){
    	   alert(res.msg);
    	   active.state.msg = res.msg;
       }
       sod.sod("replaceWidget" , widget);
	   sod.sod("updateState" );
	   var dom = getDOMByLayout(model, widget);
   	   dom.empty();
   	   init(sod, widget, dom);
   }
    
   function showSelected(sod,model,widget){
	   var active = activeRelationState(widget);
	   if(active.state.sl){
		   active.state.shsl = true;   
		   active.state.pn = 0;
	   }
	   sod.sod("replaceWidget" , widget);
	   sod.sod("updateState" );
	   var dom = getDOMByLayout(model, widget);
   	   dom.empty();
   	   init(sod, widget, dom); 
   }
   
   
   function reset(sod,model,widget){
    	var active = activeRelationState(widget);
    	active.state.f = "";
    	active.state.s = "";
    	active.state.sl = "";
    	widget.state[active.index] = active.state;
		sod.sod("replaceWidget" , widget);
    	sod.sod("updateState" );
    	var dom = getDOMByLayout(model, widget);
    	dom.empty();
    	init(sod, widget, dom);
    }
    
    function refresh(sod,model,widget){
    	var dom = getDOMByLayout(model, widget);
    	dom.empty();
    	init(sod, widget, dom);
    }
    
    function openDialog(url, opts ) {
        var html =  sod.sod("getFileByUrl",url+".html");
        var js = sod.sod("getFileByUrl",url+".js");
        var args = Array.prototype.slice.call(arguments, 2);
        var handlers = eval(js);
        var onSubmit = handlers.onSubmit || function() { this.dialog('close'); };
        var onShow = handlers.onShow;

        var width = jQuery.browser.msie ? "640px" : "auto"; // auto doesn't work in IE8

        $(".ModDialog").remove();
        var	dialog = $("<div class='ModDialog'><table style='margin: 0px auto 0px auto;'><tr><td>"+html+"</td></tr></table></div>");
        
        var d = dialog.dialog({ title: opts.title,
            width: width, height: 'auto', modal: true
        });
        var ok = i18n('button.ok'); 
        var cancel = i18n('button.cancel'); 
        d.dialog("option", "buttons", [
            { text: ok,     click: function() { onSubmit.apply(dialog, args); } },
            { text: cancel, click: function() { $(this).dialog('close'); }      }
        ]);
        
        onShow.apply(dialog, args);
    }
    
    function getQuery(sod , widget){
    	var qry = activeRelationState(widget).state.q;
    	return decode(qry);
	}
    
    function getInputQuery(sod,widget){
       return getQuery(sod , widget);
    }
    
    function getCharsPerLine(sod,widget){
    	var cpl = activeRelationState(widget).state.cpl;
    	return cpl;
    }
    
    function activeRelationState(widget){
    	var rl = widget.defRL;
    	var state;
    	var index = 0;
    	var obj ={"index" :0 , "state" : ""}; 
    	for(var i = 0 ; i < widget.state.length ; i ++){
    		var state = widget.state[i];
    		if(state.rl == rl){
    			return obj = {"index" : i , "state" : state};
    		}
    	}
    	return obj;
    }
	
    function getComponentId(sod){
    	return sod.model.cid;
    }
    
    function processMod(id, event, data , sod, widget){
    	var active = activeRelationState(widget);
    	
    	switch(event){
    	case "unitConversion":
    		active.state.u= data;
    		break;
    		
    	case "charsPerLine":
    		active.state.cpl = data;
    		break;
    		
    	case "filterByType":
    		if(data=="undefined")
    			active.state.ft= "";
    	 else
    		active.state.ft= data;
    	 
    		active.state.f= "";
    		active.state.s = "";
    		break;
    		
    	case "export":
    		var rpc =  newRpcClient();
    		rpc.sod.sodExport(sod.model.q,JSON.stringify(widget),id,data);
    		sdmDownloadFile("export.xls");
    		Richfaces.hideModalPanel("SMSTATUSDLG-status");
    		return;
    		break;
    		
    	default:
    		var arr = (!active.state.f) ? [] : active.state.f;
        	arr.push({"f":data});
        	active.state.f = arr;	
    		
    	}
    	
    
    	widget.state[active.index] = active.state;
    	sod.sod("replaceWidget" , widget);
    	sod.sod("updateState" );
    	var dom = getDOMByLayout(sod.model, widget);
    	dom.empty();
    	init(sod, widget, dom);
    	
    }
    
    function newRpcClient() {
		return new JSONRpcClient(getContextPath() + "/json-rpc");
	}
    
    function i18n(text ){
      return sod.sdmMOD("i18n" , text);
    }
       
    function esc(text ) {
      return sod.sdmMOD("esc" , text);
     }
       
    function getComponentId(sod){
      return sod.model.cid;
     }
    
    
    function hasValue(arr , obj){
        var i = arr.length;
        while (i--) {
           if (arr[i] === obj) {
               return i;
           }
        }
        return -1;
    }
    
    function getSelectionMode(mod){
    	return 'multiple';
    }

    function updateRowSelection(sod, value,widget){
    	var active = activeRelationState(widget);
    	active.state.sl = value;
    	widget.state[active.index] = active.state;
    	sod.sod("replaceWidget" , widget);
    	sod.sod("updateState" );
    }

    function getState(sod,widget){
    	var obj = activeRelationState(widget);
    	return obj.state.sl;
    }

    function getNumSelected(sod){
    	 var val = sod.find("span.sr").eq(0);
         return parseInt(val.text());
    }

    function setNumSelected(sod,value){
    	sod.find("span.sr").text(value);
    }
    
    function showOrHide (){
    	// TODO nothing
    }
    
    function getObjectType(sod){
    	return sod.find('table.ModPager').attr('ot');
    }

    function getSelectedObjects(sod,widget){
    	var active = activeRelationState(widget);
    	return active.state.sl;
    }
    
    function getPermissionCheck(mod){
    	return sod.find('table.ModPager').attr('pc');
    }
    
    function decode(text){
    	return text.replace(/&amp;/g, "&").replace(/&quot;/g, "\"")
        .replace(/&#39;/g, "'")
        .replace(/&lt;/g, "<")
        .replace(/&gt;/g, ">");
    }
    
    function toPPT(task) {
        var lego = task.lego;
        var widget = task.widget;
        var model = task.sod.model;
        if(!widget.state){
            widget.state = [];
        }
        
        var rpc = CSC.newRpcClient();
        rpc.sod.createRelationObjectsMOD(function(mod, e) {
            if(e) {
                lego.type = "Text";
                lego.data = { text: "Error: "+widget.type };
                task.cb();
                return;
            }

            mod = eval('(' + mod + ')');
            mod = $(mod.html);

            var t = mod.find('.SodTableTitle').text();
            var title = { type: "Text", text: t, bgColor: "#ddd", bold: true, padding: 2 };

            var rows = [];
            var table = { type: "Table", borderColor: "#ddd", borderWidth: 1, padding: 2, rows: rows };
            
            lego.type = "VBox";
            lego.spacing = 0;
            lego.children = [ title, table ];
            
            var cells = [];
            rows.push({ cells: cells });
            mod.find('thead th').each(function() {
                var c = { type: "Text", text: $(this).text(), bold: true, bgColor: "#eee" };
                cells.push(c);
            });
            
            mod.find('tbody tr[smrow]').each(function() {
                cells = [];
                rows.push({ cells: cells });
                $(this).find('td').each(function() {
                    // TODO get images
                    var c = { type: "Text", text: $(this).text() };
                    cells.push(c);
                });
            });

            task.cb();
        }, model.q, JSON.stringify(widget), model.cid);
    }

    return({ onInit: init, createBehavior: createBehavior, sort: sort,
             filter: filter , removeFilter: removeFilter, reset: reset,
             refresh: refresh, filterByType: filterByType,
             clearFilter: clearFilter, clearSelection: clearSelection,
             showCharsPerLine: showCharsPerLine, selectSOD: selectSOD,
             sodExport: sodExport, showSelected: showSelected,
             toPPT: toPPT});
    
})(jQueryEnterprise);


